<?php

declare(strict_types=1);

namespace app\model\oa;

use think\Model;

/**
 * 第三方发消息模型
 * @package app\model\oa
 */
class ThirdMessage extends Model
{
    /**
     * 表名（不含前缀）
     * @var string
     */
    protected $name = 'third_message';

    /**
     * 主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 自动时间戳
     * @var bool
     */
    protected $autoWriteTimestamp = false;

    /**
     * 创建时间字段
     * @var string
     */
    protected $createTime = 'create_time';

    /**
     * 更新时间字段
     * @var string
     */
    protected $updateTime = 'update_time';

    /**
     * 软删除字段
     * @var string
     */
    protected $deleteTime = 'delete_time';

    /**
     * 消息类型常量
     */
    const TYPE_EMAIL = 'email';     // 邮件
    const TYPE_WEIXIN = 'weixin';   // 企业微信
    const TYPE_MOBILE = 'mobile';   // 手机短信

    /**
     * 接收人类型常量
     */
    const RECEIVER_TYPE_USER = 1;       // 人员
    const RECEIVER_TYPE_DEPARTMENT = 2; // 部门
    const RECEIVER_TYPE_POSITION = 3;   // 岗位
    const RECEIVER_TYPE_ALL = 4;        // 全部

    /**
     * 字段类型映射
     * @var array
     */
    protected $schema = [
        'id' => 'int',
        'msgtype' => 'string',
        'types' => 'int',
        'uids' => 'string',
        'dids' => 'string',
        'pids' => 'string',
        'content' => 'string',
        'send_time' => 'int',
        'create_time' => 'int',
        'update_time' => 'int',
        'delete_time' => 'int',
    ];

    /**
     * 获取消息类型列表
     * @return array
     */
    public static function getMessageTypes(): array
    {
        return [
            self::TYPE_EMAIL => '邮件',
            self::TYPE_WEIXIN => '企业微信',
            self::TYPE_MOBILE => '手机短信',
        ];
    }

    /**
     * 获取接收人类型列表
     * @return array
     */
    public static function getReceiverTypes(): array
    {
        return [
            self::RECEIVER_TYPE_USER => '人员',
            self::RECEIVER_TYPE_DEPARTMENT => '部门',
            self::RECEIVER_TYPE_POSITION => '岗位',
            self::RECEIVER_TYPE_ALL => '全部',
        ];
    }

    /**
     * 获取接收人ID数组
     * @param string $field
     * @return array
     */
    public function getReceiverIds(string $field): array
    {
        $ids = $this->$field ?? '';
        if (empty($ids)) {
            return [];
        }
        return array_filter(array_map('intval', explode(',', $ids)));
    }

    /**
     * 获取所有接收人ID
     * @return array
     */
    public function getAllReceiverIds(): array
    {
        $userIds = $this->getReceiverIds('uids');
        $deptIds = $this->getReceiverIds('dids');
        $posIds = $this->getReceiverIds('pids');

        return [
            'users' => $userIds,
            'departments' => $deptIds,
            'positions' => $posIds,
        ];
    }

    /**
     * 获取消息内容
     * @return string
     */
    public function getContent(): string
    {
        return $this->content ?? '';
    }

    /**
     * 获取发送时间格式化
     * @return string
     */
    public function getSendTimeTextAttr(): string
    {
        return $this->send_time > 0 ? date('Y-m-d H:i:s', $this->send_time) : '未发送';
    }

    /**
     * 消息类型描述获取器
     * @param string $value
     * @return string
     */
    public function getMsgTypeTextAttr(string $value): string
    {
        $typeMap = self::getMessageTypes();
        return $typeMap[$value] ?? '未知';
    }

    /**
     * 接收人类型描述获取器
     * @param int $value
     * @return string
     */
    public function getReceiverTypeTextAttr(int $value): string
    {
        $typeMap = self::getReceiverTypes();
        return $typeMap[$value] ?? '未知';
    }

    /**
     * 根据消息类型获取记录
     * @param string $msgType
     * @return \think\Paginator
     */
    public static function getByMsgType(string $msgType)
    {
        return self::where('msgtype', $msgType)
            ->order('create_time', 'desc')
            ->paginate();
    }

    /**
     * 根据接收人类型获取记录
     * @param int $receiverType
     * @return \think\Paginator
     */
    public static function getByReceiverType(int $receiverType)
    {
        return self::where('types', $receiverType)
            ->order('create_time', 'desc')
            ->paginate();
    }

    /**
     * 获取指定时间范围内的记录
     * @param int $startTime
     * @param int $endTime
     * @return \think\model\Collection
     */
    public static function getByTimeRange(int $startTime, int $endTime)
    {
        return self::where('send_time', '>=', $startTime)
            ->where('send_time', '<=', $endTime)
            ->order('send_time', 'desc')
            ->select();
    }

    /**
     * 消息类型搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchMsgtypeAttr($query, $value)
    {
        if ($value !== '') {
            $query->where('msgtype', $value);
        }
    }

    /**
     * 接收人类型搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchTypeAttr($query, $value)
    {
        if ($value !== '') {
            $query->where('types', $value);
        }
    }

    /**
     * 发送时间范围搜索器
     * @param \think\db\Query $query
     * @param array $value
     */
    public function searchSendTimeAttr($query, array $value)
    {
        if (!empty($value[0])) {
            $query->where('send_time', '>=', strtotime($value[0]));
        }
        if (!empty($value[1])) {
            $query->where('send_time', '<=', strtotime($value[1]));
        }
    }

    /**
     * 内容搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchContentAttr($query, $value)
    {
        if ($value !== '') {
            $query->whereLike('content', '%' . $value . '%');
        }
    }

    /**
     * 获取用户ID搜索器
     * @param \think\db\Query $query
     * @param int $userId
     */
    public function searchUserIdAttr($query, int $userId)
    {
        if ($userId > 0) {
            $query->whereLike('uids', '%' . $userId . '%');
        }
    }

    /**
     * 获取部门ID搜索器
     * @param \think\db\Query $query
     * @param int $deptId
     */
    public function searchDeptIdAttr($query, int $deptId)
    {
        if ($deptId > 0) {
            $query->whereLike('dids', '%' . $deptId . '%');
        }
    }

    /**
     * 获取岗位ID搜索器
     * @param \think\db\Query $query
     * @param int $positionId
     */
    public function searchPositionIdAttr($query, int $positionId)
    {
        if ($positionId > 0) {
            $query->whereLike('pids', '%' . $positionId . '%');
        }
    }

    /**
     * 获取今日发送统计
     * @return array
     */
    public static function getTodayStats(): array
    {
        $todayStart = strtotime(date('Y-m-d 00:00:00'));
        $todayEnd = strtotime(date('Y-m-d 23:59:59'));

        $stats = self::where('send_time', '>=', $todayStart)
            ->where('send_time', '<=', $todayEnd)
            ->field('msgtype, COUNT(*) as count')
            ->group('msgtype')
            ->select()
            ->toArray();

        $result = [
            self::TYPE_EMAIL => 0,
            self::TYPE_WEIXIN => 0,
            self::TYPE_MOBILE => 0,
            'total' => 0,
        ];

        foreach ($stats as $stat) {
            if (isset($result[$stat['msgtype']])) {
                $result[$stat['msgtype']] = (int)$stat['count'];
                $result['total'] += (int)$stat['count'];
            }
        }

        return $result;
    }

    /**
     * 获取最近7天的发送统计
     * @return array
     */
    public static function getLast7DaysStats(): array
    {
        $endDate = strtotime(date('Y-m-d 23:59:59'));
        $startDate = strtotime('-6 days', strtotime(date('Y-m-d 00:00:00')));

        $stats = self::where('send_time', '>=', $startDate)
            ->where('send_time', '<=', $endDate)
            ->field("FROM_UNIXTIME(send_time, '%Y-%m-%d') as date, msgtype, COUNT(*) as count")
            ->group('date, msgtype')
            ->order('date', 'asc')
            ->select()
            ->toArray();

        $dates = [];
        $current = $startDate;
        while ($current <= $endDate) {
            $dates[date('Y-m-d', $current)] = [
                self::TYPE_EMAIL => 0,
                self::TYPE_WEIXIN => 0,
                self::TYPE_MOBILE => 0,
                'total' => 0,
            ];
            $current = strtotime('+1 day', $current);
        }

        foreach ($stats as $stat) {
            if (isset($dates[$stat['date']])) {
                $dates[$stat['date']][$stat['msgtype']] = (int)$stat['count'];
                $dates[$stat['date']]['total'] += (int)$stat['count'];
            }
        }

        return $dates;
    }
}